﻿using System.Collections.Immutable;
using System.Diagnostics;
using DimensionsHelper.LanguageService.Syntax;

namespace DimensionsHelper.LanguageService.Symbols;

/// <summary>
///     声明文件中的枚举定义符号
/// </summary>
public class EnumSymbol : AbstractTypeSymbol
{
    private readonly List<int> _values = [];

    internal EnumSymbol(EnumSignature signature, ModuleSymbol? containingModule) :
        base(SymbolKinds.NamedType, TypeKinds.Enum)
    {
        Declaration = signature;
        ContainingModule = containingModule;
    }


    public override string Name => Declaration.Name;

    public override bool IsEnum => true;


    /// <summary>
    ///     获取枚举成员的值列表，顺序和声明顺序相同。
    /// </summary>
    public ImmutableArray<int> Values => [.._values];


    /// <summary>
    ///     枚举声明语法节点
    /// </summary>
    public override EnumSignature Declaration { get; }


    /// <summary>
    ///     声明语法所在的模块符号，可以是 <see langword="null" />
    /// </summary>
    public override ISymbol? ContainingModule { get; }


    /// <summary>
    ///     包含此枚举符号的符号声明，和<see cref="ContainingModule" />相同。
    /// </summary>
    public override ISymbol? ContainingSymbol => ContainingModule;


    /// <summary>
    ///     如果枚举中包含指定数值，返回<see langword="true" />。
    /// </summary>
    public bool ContainsValue(int value)
    {
        return _values.Contains(value);
    }


    internal override bool TryAddMember(ISymbol member)
    {
        Debug.Assert(member is EnumMemberSymbol);
        EnumMemberSymbol enumSymbol = (EnumMemberSymbol)member;
        _values.Add(enumSymbol.Value);
        return base.TryAddMember(member);
    }


    public override bool IsAssignableFrom(ITypeSymbol type)
    {
        // 向此类符号赋值时，一般情况下，当前符号作为绑定类型，此时，枚举成员和整型数字都可以赋值给当前绑定
        return type == ValueTypeSymbol.Long || ReferenceEquals(this, type) || this == type.ContainingSymbol;
    }
}